package com.hhd.flow.engine.cmd.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.hhd.flow.engine.cmd.PassTaskContext;
import com.hhd.flow.engine.utils.CommonUtils;
import com.hhd.flow.engine.utils.FlowUtils;
import com.hhd.flow.engine.vo.*;
import com.hhd.flow.entity.FlowComment;
import com.hhd.flow.entity.FlowProcessInstance;
import com.hhd.flow.entity.FlowUserTask;
import com.hhd.flow.exception.FlowException;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.SuperBuilder;

import java.util.List;
import java.util.stream.Collectors;

@Setter
@Getter
@SuperBuilder(toBuilder = true)
public class CountUserSignCommand extends FlowUserTaskChangeCommand<Void> {
    private String flowUserTaskId;
    UserTask userTask;

    //下面是运行时的参数
    private JSONArray userConfigs;
    private String taskName;
    private List<FlowUser> flowUsers;
    private FlowUserTask flowUserTask;
    private FlowModel flowModel;
    private FlowProcessInstance flowProcessInstance;
    private UserTask currentUserTask;
    private FlowComment comment;

    @Override
    public Void execute() {
        prepare();

        publishBeforeAddSignEvent();

        createUserTaskDefinition();

        createComment();

        addSign();

        publishAfterAddSignEvent();
        return null;
    }

    private void createComment() {
        comment = FlowUtils.createComment(flowUserTask, createCommentMessage(), null, null, CommentType.addUserSign, null);
        if (!CommonUtils.isEmpty(userConfigs)) {
            comment.setCommentInfo(JSONObject.toJSONString(userConfigs));
        }
        getEngine().getFlowCommentService().save(comment);
    }

    private String createCommentMessage() {
//        return "加签给：" + flowUsers.stream().map(FlowUser::getUsername).collect(Collectors.joining(","));
        return null;
    }

    private void addSign() {
        flowModel = flowModel.addUserTaskAfter(userTask, currentUserTask.getId());
        flowProcessInstance.setModel(flowModel.getModelString());
        getEngine().getFlowProcessInstanceService().updateById(flowProcessInstance);
    }

    private void publishBeforeAddSignEvent() {

    }

    private void publishAfterAddSignEvent() {
        afterChangeFlowUserTask(flowProcessInstance); //触发创建用户任务的事件
    }

    private void createUserTaskDefinition() {
        userTask = new UserTask();
        userTask.setId(IdWorker.getIdStr());
        userTask.setType(FlowNode.FlowNodeType.userTask.name());
        userTask.setTaskName(getTaskName());
        userTask.setExecuteWay(UserTask.ExecuteWay.multi);
        userTask.setExecuteThreshold(100);
        userTask.setActionAuth(currentUserTask.getActionAuth());
        userTask.setNotify(false);
        userTask.setManualSelectUser(false);
        userTask.setAutoComplete(false);
        userTask.setMustSignature(false);
        userTask.setAddCountSign(true);
        userTask.setAddCountSignUsers(flowUsers.stream().map(FlowUser::getId).collect(Collectors.joining(",")));
        userTask.setAddCountSignUserNames(flowUsers.stream().map(FlowUser::getUsername).collect(Collectors.joining(",")));
        userTask.setUserConfigs(null);
        userTask.setPcView(currentUserTask.getPcView());
        userTask.setPcAction(currentUserTask.getPcAction());
        userTask.setMobileView(currentUserTask.getMobileView());
        userTask.setMobileAction(currentUserTask.getMobileAction());

        userTask.setCountFrom(getEngine().getCurrentUser().getId());
        userTask.setCountFromUsername(getEngine().getCurrentUser().getUsername());
        userTask.setCountFromTaskDefinitionId(currentUserTask.getId());
        userTask.setCountFromTaskId(userTask.getId());
        userTask.setUserConfigs(userConfigs);
    }

    private void prepare() {
        flowUserTask = getEngine().getFlowUserTaskService().getById(flowUserTaskId);
        CommonUtils.isEmptyThrow(flowUserTask, new FlowException("没有找到用户任务：" + flowUserTaskId));
        if (flowUserTask.getNotify()) {
            throw new FlowException("知会任务不支持加签的操作");
        }

        flowProcessInstance = getEngine().getFlowProcessInstanceService().getById(flowUserTask.getProcessInstanceId());
        CommonUtils.isEmptyThrow(flowProcessInstance, new FlowException("没有找到流程实例：" + flowUserTask.getProcessInstanceId()));

        flowModel = loadFlowModelByProcessInstanceId(flowProcessInstance.getId());
        CommonUtils.isEmptyThrow(flowProcessInstance, new FlowException("没有找到流程定义"));

        currentUserTask = flowModel.getUserTaskById(flowUserTask.getTaskDefinitionId());

        getFlowUsersFromEngine();

        if (!CommonUtils.isEmpty(userTask)) {
            userConfigs = userTask.getUserConfigs();
        }
        beforeChangeFlowUserTask(flowProcessInstance);
    }

    private void getFlowUsersFromEngine() {
        taskName = userTask.getTaskName();
        PassTaskContext context = PassTaskContext.builder()
                .variablesContainer(getVariablesContainer(flowUserTask.getFormTypeId(), flowUserTask.getFormId(), flowProcessInstance, getFormModel()))
                .formTypeId(flowUserTask.getFormTypeId())
                .formId(flowUserTask.getFormId())
                .flowTaskId(flowUserTask.getTaskInstanceId())
                .flowProcessInstanceId(flowProcessInstance.getId())
                .userManualSelect(null)
                .formModel(null).build();
        flowUsers = getEngine().loadFlowUser(flowUserTask.getFormTypeId(), flowUserTask.getFormId(), userTask, context);
    }
}
